﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using System.Configuration;
using Intorise.Game.MU.Entity;
using Newtonsoft.Json;
using System.Net;
using System.Collections.Concurrent;
using System.Collections;

/// <summary>
///Helper 的摘要说明
/// </summary>
public class Helper
{
    static readonly object waitLocker = new object();
    static readonly object completedLocker = new object();
    static readonly object totalCountLocker = new object();
    static readonly object loginningLocker = new object();
    static DateTime begin = DateTime.Now;

    static readonly ConcurrentQueue<LoginEntity> waitQuere = new ConcurrentQueue<LoginEntity>();
    static readonly List<LoginEntity> loginningQuere = new List<LoginEntity>();
    static readonly List<LoginEntity> completedQuere = new List<LoginEntity>();

    static string serverRootPath = "";
    static int serverTimeout = 5;
    static double peerRegisterSecondCount = 0;
    static double maxPeerRegisterSecondCount = 0;
    static double peerLoginSecondCount = 0;
    static double maxPeerCompletedSecondCount = 0;
    static int completedCount = 0;
    static int ProcessPerCount = 5;
    static int totalCount = 0;
    static int loginningCount = 0;

    static Helper()
    {
        if (!int.TryParse(ConfigurationManager.AppSettings["ServerTimeout"], out serverTimeout))
        {
            serverTimeout = 5;
        }
        if (!int.TryParse(ConfigurationManager.AppSettings["ProcessPerCount"], out ProcessPerCount))
        {
            ProcessPerCount = 5;
        }

        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                Thread.Sleep(1000 * 60 * 10);
                lock (loginningLocker)
                {
                    var list = loginningQuere.Where(w => w.RegisterTime.HasValue && (DateTime.Now - w.RegisterTime.Value).TotalMinutes > 10).ToList();
                    list.ForEach(f =>
                    {
                        loginningQuere.Remove(f);
                        Logs.Log("移除：" + f.Account + " " + f.ServerNo + " " + f.RegisterTime.Value);
                    });
                }
            }
        });
    }

    /// <summary>
    /// 最高每秒登录数
    /// </summary>
    public static double MaxCompletedPeerSecondCount
    {
        get
        {
            return maxPeerCompletedSecondCount;
        }
    }

    /// <summary>
    /// 每秒登录数
    /// </summary>
    public static double PeerCompletedSecondCount
    {
        get
        {
            var time = (int)(DateTime.Now - begin).TotalSeconds;
            if (time <= 0)
            {
                time = 1;
            }
            peerLoginSecondCount = Math.Round((double)CompletedCount / time, 2);
            if (maxPeerCompletedSecondCount < peerLoginSecondCount) { maxPeerCompletedSecondCount = peerLoginSecondCount; }
            return peerLoginSecondCount;
        }
    }

    /// <summary>
    /// 最高每秒注册数
    /// </summary>
    public static double MaxRegisterPeerSecondCount
    {
        get
        {
            return maxPeerRegisterSecondCount;
        }
    }

    /// <summary>
    /// 每秒注册数
    /// </summary>
    public static double PeerRegisterSecondCount
    {
        get
        {
            var time = (int)(DateTime.Now - begin).TotalSeconds;
            if (time <= 0)
            {
                time = 1;
            }
            peerRegisterSecondCount = Math.Round((double)TotalCount / time, 2);
            if (maxPeerRegisterSecondCount < peerRegisterSecondCount) { maxPeerRegisterSecondCount = peerRegisterSecondCount; }
            return peerRegisterSecondCount;
        }
    }

    /// <summary>
    /// 已完成的账户数
    /// </summary>
    public static int CompletedCount
    {
        get
        {
            lock (completedLocker)
            {
                return completedCount;
            }
        }
    }

    /// <summary>
    /// 总账户数
    /// </summary>
    public static int TotalCount
    {
        get
        {
            lock (totalCountLocker)
            {
                return totalCount;
            }
        }
    }

    /// <summary>
    /// 等待登录的账户数
    /// </summary>
    public static int WaitingCount
    {
        get
        {
            return waitQuere.Count();
        }
    }

    /// <summary>
    /// 正在登录的账户数
    /// </summary>
    public static int LoginingCount
    {
        get
        {
            lock (loginningLocker)
            {
                return loginningQuere.Count;
            }
        }
    }

    public static void Init(string rootPath)
    {
        serverRootPath = rootPath;
        return;
        Task.Factory.StartNew(() =>
        {

        });

        #region 计算注册速度
        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                int current = TotalCount;
                Thread.Sleep(1000 * 60);
                var temp = TotalCount - current;
                peerRegisterSecondCount = temp / 60;
                if (peerRegisterSecondCount > maxPeerRegisterSecondCount)
                {
                    maxPeerRegisterSecondCount = peerRegisterSecondCount;
                }
            }
        });
        #endregion

        #region 计算登录速度
        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                int current = CompletedCount;
                Thread.Sleep(1000 * 60);
                var temp = CompletedCount - current;
                peerLoginSecondCount = temp / 60;
                if (peerLoginSecondCount > maxPeerCompletedSecondCount)
                {
                    maxPeerCompletedSecondCount = peerLoginSecondCount;
                }
            }
        });
        #endregion
    }

    /// <summary>
    /// 获取当前正在登录的账号
    /// </summary>
    /// <returns></returns>
    public static List<LoginEntity> GetLoginingEntity()
    {
        lock (loginningLocker)
        {
            return loginningQuere.Where(w => w.LoginStatus == LoginStatusEnum.Logining).ToList();
        }
    }

    public static LoginEntity GetNeedLoginEntity()
    {
        lock (waitLocker)
        {
            LoginEntity entity = null;

            waitQuere.TryDequeue(out entity);
            return entity;
        }
    }

    public static List<LoginEntity> GetNeedLoginEntities()
    {
        LoginEntity entity = null;
        List<LoginEntity> list = new List<LoginEntity>(ProcessPerCount);
        for (var i = 0; i < ProcessPerCount; i++)
        {
            if (waitQuere.TryDequeue(out entity))
            {
                entity.LoginStatus = LoginStatusEnum.Logining;
                list.Add(entity);
                lock (loginningLocker)
                {
                    loginningQuere.Add(entity);
                }
            }
        }
        return list;
    }

    public static LoginEntity RegisterEntity(LoginEntity loginEntity)
    {
        LoginEntity entity = null;
        lock (completedLocker)
        {
            entity = completedQuere.FirstOrDefault(f => f.Account == loginEntity.Account && f.ServerNo == loginEntity.ServerNo);
            if (entity != null)
            {
                completedQuere.Remove(entity);
                return entity;
            }
        }

        lock (loginningLocker)
        {
            entity = loginningQuere.FirstOrDefault(f => f.Account == loginEntity.Account && f.ServerNo == loginEntity.ServerNo);
            if (entity != null)
            {
                return entity;
            }
        }

        entity = waitQuere.FirstOrDefault(f => f.Account == loginEntity.Account && f.ServerNo == loginEntity.ServerNo);
        if (entity != null)
        {
            return entity;
        }

        lock (totalCountLocker)
        {
            totalCount++;
        }
        loginEntity.LoginStatus = LoginStatusEnum.Waiting;
        loginEntity.RegisterTime = DateTime.Now;
        waitQuere.Enqueue(loginEntity);
        return loginEntity;
    }

    public static void LoginComplete(LoginEntity submitEntity)
    {
        LoginEntity entity = null;

        lock (loginningLocker)
        {
            entity = loginningQuere.FirstOrDefault(f => f.Account == submitEntity.Account && f.ServerNo == submitEntity.ServerNo);
            if (entity == null) { return; }
            loginningCount--;
            entity.LoginResult = submitEntity.LoginResult;
            entity.LoginStatus = LoginStatusEnum.Completed;
            entity.Port = submitEntity.Port;
            entity.ServerIP = submitEntity.ServerIP;
            entity.ServerNo = submitEntity.ServerNo;
            entity.Sign = submitEntity.Sign;
            entity.TicketTime = submitEntity.TicketTime;
            entity.CompletedTime = DateTime.Now;
            entity.Cookies = submitEntity.Cookies;
            loginningQuere.Remove(entity);

            lock (completedLocker)
            {
                completedQuere.Add(entity);
                completedCount++;
            }
        }
    }

    public static void Remove(LoginEntity submitEntity)
    {

    }
}